#ifndef GUDB_CONNECTION_POOL_H
#define GUDB_CONNECTION_POOL_H

#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "network_protocol.h"
#include "../utils/perf_monitor.h"

#ifdef __cplusplus
extern "C" {
#endif

// Connection pool configuration
typedef struct {
    uint32_t max_connections;           // Maximum number of connections
    uint32_t min_connections;           // Minimum number of pre-allocated connections
    uint32_t initial_connections;       // Initial number of connections to create
    uint32_t connection_timeout_sec;    // Connection idle timeout (seconds)
    uint32_t cleanup_interval_sec;      // How often to clean up idle connections
    uint32_t max_queue_size;            // Maximum size of connection request queue
    bool enable_connection_reuse;       // Whether to reuse connections
    bool enable_keepalive;              // Enable TCP keepalive
    uint32_t keepalive_time_sec;        // Keepalive time in seconds
    uint32_t max_requests_per_conn;     // Max requests per connection before recycling
} connection_pool_config_t;

// Connection pool statistics
typedef struct {
    uint64_t total_connections_created; // Total connections created since start
    uint64_t total_connections_destroyed; // Total connections destroyed
    uint64_t current_active_connections; // Currently active connections
    uint64_t current_idle_connections;   // Currently idle connections
    uint64_t peak_connections;           // Peak concurrent connections
    uint64_t connection_requests;        // Total connection requests
    uint64_t connection_wait_timeouts;   // Connection requests that timed out
    uint64_t connection_pool_hits;       // Connections served from pool
    uint64_t connection_pool_misses;     // New connections created
    uint64_t connections_recycled;       // Connections recycled due to limits
    double avg_connection_lifetime_sec;  // Average connection lifetime
    double avg_wait_time_ms;            // Average wait time for connections
    time_t last_cleanup_time;           // Last cleanup operation time
    uint32_t cleanup_operations;        // Number of cleanup operations performed
} connection_pool_stats_t;

// Connection state in pool
typedef enum {
    POOL_CONN_STATE_FREE = 0,           // Available for assignment
    POOL_CONN_STATE_ACTIVE,             // Currently handling requests
    POOL_CONN_STATE_IDLE,               // Connected but not handling requests
    POOL_CONN_STATE_CLOSING,            // Being closed
    POOL_CONN_STATE_ERROR               // Connection has error
} pool_connection_state_t;

// Pool connection wrapper
typedef struct pool_connection {
    mysql_connection_t* mysql_conn;     // Underlying MySQL connection
    pool_connection_state_t pool_state; // State in pool
    time_t created_time;                // When connection was created
    time_t last_used_time;              // Last time connection was used
    uint64_t request_count;             // Number of requests handled
    uint64_t total_bytes_sent;          // Total bytes sent on this connection
    uint64_t total_bytes_received;      // Total bytes received
    bool marked_for_cleanup;            // Whether to clean up this connection
    
    // Threading support
    pthread_mutex_t conn_mutex;         // Mutex for this connection
    pthread_t handler_thread;           // Thread handling this connection
    bool thread_active;                 // Whether handler thread is active
    
    // Pool management
    struct pool_connection* next;       // Next in linked list
    struct pool_connection* prev;       // Previous in linked list
    uint32_t pool_slot_id;              // Slot ID in pool array
} pool_connection_t;

// Connection request queue entry
typedef struct connection_request {
    pthread_cond_t wait_cond;           // Condition variable for waiting
    pthread_mutex_t wait_mutex;         // Mutex for condition variable
    pool_connection_t* assigned_conn;   // Assigned connection (NULL if pending)
    time_t request_time;                // When request was made
    uint32_t timeout_sec;               // Request timeout
    bool completed;                     // Whether request was completed
    bool timed_out;                     // Whether request timed out
    
    struct connection_request* next;    // Next in queue
} connection_request_t;

// Connection pool manager
typedef struct connection_pool {
    connection_pool_config_t config;    // Pool configuration
    connection_pool_stats_t stats;      // Pool statistics
    gudb* database;                     // Database instance
    perf_monitor_t* perf_monitor;       // Performance monitor
    
    // Connection storage
    pool_connection_t** connections;    // Array of connection pointers
    uint32_t total_slots;               // Total connection slots allocated
    uint32_t used_slots;                // Currently used slots
    
    // Free connection management
    pool_connection_t* free_list_head;  // Head of free connections list
    pool_connection_t* free_list_tail;  // Tail of free connections list
    uint32_t free_count;                // Number of free connections
    
    // Active connection management
    pool_connection_t* active_list_head; // Head of active connections list
    pool_connection_t* active_list_tail; // Tail of active connections list
    uint32_t active_count;              // Number of active connections
    
    // Connection request queue
    connection_request_t* request_queue_head; // Head of request queue
    connection_request_t* request_queue_tail; // Tail of request queue
    uint32_t queue_size;                // Current queue size
    
    // Threading and synchronization
    pthread_mutex_t pool_mutex;         // Main pool mutex
    pthread_cond_t pool_cond;           // Condition variable for pool changes
    pthread_rwlock_t stats_lock;        // Read-write lock for statistics
    
    // Background threads
    pthread_t cleanup_thread;           // Cleanup thread
    pthread_t monitor_thread;           // Monitoring thread
    bool threads_running;               // Whether background threads are running
    
    // Pool state
    bool initialized;                   // Whether pool is initialized
    bool shutting_down;                 // Whether pool is shutting down
    time_t start_time;                  // When pool was started
    time_t last_stats_update;           // Last statistics update time
} connection_pool_t;

// Lifecycle functions
connection_pool_t* connection_pool_create(const connection_pool_config_t* config, 
                                         gudb* database);
int connection_pool_init(connection_pool_t* pool);
void connection_pool_destroy(connection_pool_t* pool);
int connection_pool_start_background_threads(connection_pool_t* pool);
int connection_pool_stop_background_threads(connection_pool_t* pool);

// Connection management
pool_connection_t* connection_pool_acquire(connection_pool_t* pool, 
                                          uint32_t timeout_sec);
int connection_pool_release(connection_pool_t* pool, pool_connection_t* conn);
int connection_pool_close_connection(connection_pool_t* pool, pool_connection_t* conn);

// Connection lifecycle
pool_connection_t* connection_pool_create_connection(connection_pool_t* pool, 
                                                    int sockfd, 
                                                    struct sockaddr_in* client_addr);
int connection_pool_recycle_connection(connection_pool_t* pool, pool_connection_t* conn);
int connection_pool_cleanup_idle_connections(connection_pool_t* pool);

// Statistics and monitoring
int connection_pool_get_stats(connection_pool_t* pool, connection_pool_stats_t* stats);
int connection_pool_update_stats(connection_pool_t* pool);
void connection_pool_print_stats(connection_pool_t* pool);
uint32_t connection_pool_get_active_count(connection_pool_t* pool);
uint32_t connection_pool_get_free_count(connection_pool_t* pool);
bool connection_pool_is_healthy(connection_pool_t* pool);

// Configuration and tuning
int connection_pool_set_max_connections(connection_pool_t* pool, uint32_t max_connections);
int connection_pool_set_timeout(connection_pool_t* pool, uint32_t timeout_sec);
int connection_pool_resize(connection_pool_t* pool, uint32_t new_size);

// Background thread functions
void* connection_pool_cleanup_thread_func(void* arg);
void* connection_pool_monitor_thread_func(void* arg);

// Utility functions
bool connection_pool_is_connection_expired(pool_connection_t* conn, 
                                          uint32_t timeout_sec);
bool connection_pool_should_recycle_connection(pool_connection_t* conn, 
                                              uint32_t max_requests);
int connection_pool_validate_connection(pool_connection_t* conn);

// Default configuration
static inline connection_pool_config_t connection_pool_default_config(void) {
    connection_pool_config_t config = {
        .max_connections = 10000,           // Support high concurrency
        .min_connections = 100,             // Keep minimum connections ready
        .initial_connections = 200,         // Start with reasonable number
        .connection_timeout_sec = 300,      // 5 minute timeout
        .cleanup_interval_sec = 60,         // Cleanup every minute
        .max_queue_size = 1000,             // Large queue for high load
        .enable_connection_reuse = true,    // Enable connection reuse
        .enable_keepalive = true,           // Enable TCP keepalive
        .keepalive_time_sec = 120,          // 2 minute keepalive
        .max_requests_per_conn = 10000      // Recycle after 10K requests
    };
    return config;
}

// Performance monitoring integration macros
#define POOL_PERF_CONNECTION_CREATED(pool) \
    do { if ((pool)->perf_monitor) perf_monitor_connection_opened((pool)->perf_monitor); } while(0)

#define POOL_PERF_CONNECTION_DESTROYED(pool) \
    do { if ((pool)->perf_monitor) perf_monitor_connection_closed((pool)->perf_monitor); } while(0)

#define POOL_PERF_UPDATE_METRICS(pool) \
    do { if ((pool)->perf_monitor) perf_monitor_update_metrics((pool)->perf_monitor); } while(0)

#ifdef __cplusplus
}
#endif

#endif // GUDB_CONNECTION_POOL_H